﻿namespace Resharper.Abstractions.CodeDom.Expressions
{
  using JetBrains.Annotations;
  using JetBrains.ReSharper.Psi.CSharp.Tree;
  using JetBrains.ReSharper.Psi.Tree;
  using Resharper.Abstractions.CodeDom.Expressions.BinaryExpressions;
  using Resharper.Abstractions.CodeDom.Expressions.BinaryExpressions.AdditiveExpressions;
  using Resharper.Abstractions.CodeDom.Expressions.BinaryExpressions.EqualityExpressions;
  using Resharper.Abstractions.CodeDom.Expressions.BinaryExpressions.RelationalExpressions;
  using Resharper.Abstractions.CodeDom.Expressions.InvocationExpressions;
  using Resharper.Abstractions.CodeDom.Expressions.LiteralExpressions;
  using Resharper.Abstractions.CodeDom.Expressions.PostFixOperatorExpressions;
  using Resharper.Abstractions.CodeDom.Expressions.PrimaryExpressions;
  using Resharper.Abstractions.CodeDom.Expressions.UnaryOperatorExpressions;

  /// <summary>Defines the <see cref="ExpressionFactory"/> class.</summary>
  internal static class ExpressionFactory
  {
    #region Public Methods

    /// <summary>Gets the expression.</summary>
    /// <param name="expression">The expression.</param>
    /// <returns>Returns the expression.</returns>
    [NotNull]
    public static Expression GetExpression(IExpression expression)
    {
      if (expression is ILiteralExpression)
      {
        return new LiteralExpression((ILiteralExpression)expression);
      }

      if (expression is IAdditiveExpression)
      {
        return new AdditiveExpression((IAdditiveExpression)expression);
      }

      if (expression is IUnaryOperatorExpression)
      {
        return new UnaryOperatorExpression((IUnaryOperatorExpression)expression);
      }

      if (expression is IRelationalExpression)
      {
        return new RelationalExpression((IRelationalExpression)expression);
      }

      if (expression is IEqualityExpression)
      {
        return new EqualityExpression((IEqualityExpression)expression);
      }

      if (expression is IBinaryExpression)
      {
        return new BinaryExpression((IBinaryExpression)expression);
      }

      if (expression is IInvocationExpression)
      {
        return new InvocationExpression((IInvocationExpression)expression);
      }

      if (expression is IPostfixOperatorExpression)
      {
        return new PostFixOperatorExpression((IPostfixOperatorExpression)expression);
      }

      if (expression is IPrimaryExpression)
      {
        return new PrimaryExpression((IPrimaryExpression)expression);
      }

      return new Expression(expression);
    }

    #endregion
  }
}